package com.rockcent.mall.lib.repository;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rockcent.common.common.PageResult;
import com.rockcent.common.common.SQLObjectDoing;
import com.rockcent.common.common.SQLPageDoing;
import com.rockcent.mall.lib.dto.CustomerDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

/**
 * Created by zhangjh on 2016/10/14.
 */
@Repository
public class CustomerRepositoryImpl implements CustomerRepositoryCustom {

    private static final Logger log = LoggerFactory.getLogger(CustomerRepositoryImpl.class);

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    @Autowired
    private ObjectMapper objectMapper;


    public PageResult getCustomerPage(String nickName, Long merchantId, Long mallId, PageResult pageResult) {
        SQLPageDoing<CustomerDto> doing = (sql, fields, params, typeReferenceMap) -> {
            sql.append("SELECT %s FROM merchant_order mo LEFT JOIN customer c");
            sql.append(" ON c.id = mo.customer_id");
            sql.append(" WHERE mo.customer_id IS NOT NULL");
            sql.append(" AND c.mall_id =:mallId");
            sql.append(" AND mo.merchant_id=:merchantId");
            params.put("mallId", mallId);
            params.put("merchantId", merchantId);
            fields.append("DISTINCT c.id,c.nick_name as nickName");
        };
        return doing.go(pageResult, CustomerDto.class, objectMapper, jdbcTemplate, log);
    }

    @Override
    public Long getCustomerOrderCount(Long customerId, Long merchantId, Long mallId, PageResult pageResult) {

            SQLObjectDoing<CustomerDto> doing = (sql, fields, params, typeReferenceMap) -> {
                sql.append("select %s from merchant_order mo where mo.customer_id =:customerId");
                sql.append(" AND mo.customer_id IS NOT NULL");
                sql.append(" AND mo.mall_id =:mallId");
                sql.append(" AND mo.merchant_id=:merchantId");
                params.put("customerId", customerId);
                params.put("mallId", mallId);
                params.put("merchantId", merchantId);
                fields.append("count(mo.id) as orderCount");
            };
        CustomerDto count = doing.go(CustomerDto.class, jdbcTemplate, log, objectMapper);


        return count.getOrderCount();
    }


    @Override
    public Long getCustomerProductTotal(Long customerId, Long merchantId, Long mallId, PageResult pageResult) {


            SQLObjectDoing<CustomerDto> doing = (sql, fields, params, typeReferenceMap) -> {
                sql.append("SELECT %s FROM merchant_order_item mi");
                sql.append(" LEFT JOIN merchant_order mo ON mo.`id`=mi.`merchant_order_id`");
                sql.append(" where mo.customer_id =:customerId");
                sql.append(" AND mo.`customer_id` IS NOT NULL");
                sql.append(" AND mo.`mall_id`=:mallId");
                sql.append(" AND mo.`merchant_id`=:merchantId");

                params.put("customerId", customerId);
                params.put("mallId", mallId);
                params.put("merchantId", merchantId);
                fields.append("sum(mi.buy_count) as buyCount");
            };
            CustomerDto count = doing.go(CustomerDto.class, jdbcTemplate, log, objectMapper);


        return count.getBuyCount();
    }

    @Override
    public Long getCustomerProductVerificationTotal( Long customerId, Long mallId, Long merchantId, PageResult pageResult) {


            SQLObjectDoing<CustomerDto> doing = (sql, fields, params, typeReferenceMap) -> {
                sql.append("SELECT %s FROM merchant_order_verification mv");
                sql.append(" LEFT JOIN merchant_order_item mi ON mi.`id`=mv.`merchant_order_item_id`");
                sql.append(" LEFT JOIN merchant_order mo ON mo.id=mi.merchant_order_id");
                sql.append(" WHERE mv.merchant_id =:merchantId AND mo.mall_id=:mallId AND mo.customer_id=:customerId");

                params.put("customerId", customerId);
                params.put("mallId", mallId);
                params.put("merchantId", merchantId);
                fields.append("SUM(mv.`remain_count`)AS remainCount");
            };
            CustomerDto count = doing.go(CustomerDto.class, jdbcTemplate, log, objectMapper);


        return count.getRemainCount();
    }

    @Override
    public Double getCustomerOrderTotal( Long customerId , Long merchantId, Long mallId, PageResult pageResult) {

            SQLObjectDoing<CustomerDto> doing = (sql, fields, params, typeReferenceMap) -> {
                sql.append("SELECT %s FROM merchant_order mo " +
                        "  where mo.customer_id =:customerId " +
                        "  and mo.`customer_id`=:customerId AND mo.`mall_id`=:mallId AND mo.`merchant_id`=:merchantId");
                params.put("customerId", customerId);
                params.put("mallId", mallId);
                params.put("merchantId", merchantId);
                fields.append("SUM(mo.amount) as amount");
            };
            CustomerDto count = doing.go(CustomerDto.class, jdbcTemplate, log, objectMapper);

        return count.getAmount();
    }

    @Override
    public Long getCustomerProductBack(Long customerId , Long merchantId, Long mallId, PageResult pageResult) {

            SQLObjectDoing<CustomerDto> doing = (sql, fields, params, typeReferenceMap) -> {
                sql.append("SELECT %s FROM merchant_order_item mi " +
                        " LEFT JOIN merchant_order mo ON mo.`id`= mi.`merchant_order_id`" +
                        " WHERE mo.`customer_id`=:customerId AND mo.`mall_id`=:mallId AND mo.`merchant_id`=:merchantId");
                sql.append(" AND mo.`status` IN('FINISHED_REJECT','FINISHED_REFUND')");
                params.put("customerId", customerId);
                params.put("mallId", mallId);
                params.put("merchantId", merchantId);
                fields.append(" SUM(mi.buy_count) as productBack");
            };
            CustomerDto count = doing.go(CustomerDto.class, jdbcTemplate, log, objectMapper);

        return count.getProductBack();
    }

}
